﻿using System.Collections.Generic;
using System.Linq;
using Algoritmia.Problems.Puzzles.NQueens;

namespace Demos.Problems.Nqueens
{
    class ObservableNQueensEnumerator2 : NQueensEnumerator2
    {
        public event ReinaHandler ColocarReina;
        public event ReinaHandler RetirarReina;

        override protected IEnumerable<NQueensStateSpace2.State> Backtracking(NQueensStateSpace2.State state,
            NQueensStateSpace2 space, Algoritmia.DataStructures.Lists.IList<int> decisions)
        {
            if (space.IsFinal(state))
            {
                yield return state;
            }

            foreach (var decision in space.Decisions(state))
            {
                decisions.Add(decision);
                if (ColocarReina != null) ColocarReina(decision);
                state = space.Decide(state, decision);
                foreach (var result in Backtracking(state, space, decisions))
                {
                    yield return result;
                }
                if (RetirarReina != null) RetirarReina(decisions.Last());
                decisions.RemoveAt(decisions.Count - 1);
                state = space.Undo(state, decision);
            }
        }

        public IEnumerable<Algoritmia.DataStructures.Lists.IList<int>> Enumerate(NQueensStateSpace2 space)
        {
            var decisions = _createList();
            var initial = space.InitialStates.First();
            if (initial != null)
            {
                foreach (var result in Backtracking(initial, space, decisions))
                {
                    ColocarReina = null;
                    RetirarReina = null;
                    yield return result.ToList();
                }
            }
        }
    }
}
